package com.ruoyi.system.service.impl;

import cn.hutool.core.date.DateUtil;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.domain.vo.AssesRankVo;
import com.ruoyi.system.mapper.AssesManagementMapper;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 积分管理Service业务层处理
 *
 * @author ruoyi
 * @date 2024-04-22
 */
@Service
public class AssesManagementServiceImpl implements IAssesManagementService
{
    @Autowired
    private AssesManagementMapper assesManagementMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private IAssesRuleService assesRuleService;
    @Autowired
    private IMeetingManagementService meetingManagementService;
    @Autowired
    private IActivityManagementService activityManagementService;
    @Autowired
    private ISysDeptService sysDeptService;
    @Autowired
    private IWorkSummaryService workSummaryService;



    /**
     * 查询积分管理
     *
     * @param id 积分管理主键
     * @return 积分管理
     */
    @Override
    public AssesManagement selectAssesManagementById(Long id)
    {
        AssesManagement management = assesManagementMapper.selectAssesManagementById(id);
        String fileUrl = management.getFileUrl();
        if(StringUtils.isNotBlank(fileUrl)){
            List<String> fileUrlList = Arrays.asList(fileUrl.split(","));
            management.setFileUrlList(fileUrlList);
        }
        return management;
    }

    /**
     * 查询积分管理列表
     *
     * @param assesManagement 积分管理
     * @return 积分管理
     */
    @Override
    public List<AssesManagement> selectAssesManagementList(AssesManagement assesManagement)
    {
        List<AssesManagement> assesManagements = assesManagementMapper.selectAssesManagementList(assesManagement);
        for(AssesManagement management : assesManagements){
            String fileUrl = management.getFileUrl();
            if(StringUtils.isNotBlank(fileUrl)){
                List<String> fileUrlList = Arrays.asList(fileUrl.split(","));
                management.setFileUrlList(fileUrlList);
            }
        }
        return assesManagements;
    }

    /**
     * 新增积分管理
     *
     * @param assesManagement 积分管理
     * @return 结果
     */
    @Override
    public int insertAssesManagement(AssesManagement assesManagement)
    {
        assesManagement.setCreateTime(DateUtils.getNowDate());
        List<String> fileUrlList = assesManagement.getFileUrlList();
        if(!CollectionUtils.isEmpty(fileUrlList)){
            String fileUrl = StringUtils.join(fileUrlList, ",");
            assesManagement.setFileUrl(fileUrl);
        }
        return assesManagementMapper.insertAssesManagement(assesManagement);
    }

    /**
     * 修改积分管理
     *
     * @param assesManagement 积分管理
     * @return 结果
     */
    @Override
    public int updateAssesManagement(AssesManagement assesManagement)
    {
        assesManagement.setUpdateTime(DateUtils.getNowDate());
        List<String> fileUrlList = assesManagement.getFileUrlList();
        String fileUrl = StringUtils.join(fileUrlList, ",");
        assesManagement.setFileUrl(fileUrl);
        return assesManagementMapper.updateAssesManagement(assesManagement);
    }

    /**
     * 删除积分管理信息
     *
     * @param id 积分管理主键
     * @return 结果
     */
    @Override
    public int deleteAssesManagementById(Long id)
    {
        return assesManagementMapper.deleteAssesManagementById(id);
    }

    /**
     * 修改状态
     *
     * @param assesManagement 积分管理
     * @return 结果
     */
    @Override
    public int updateAssesManagementStatus(AssesManagement assesManagement){
        AssesManagement management = new AssesManagement();
        management.setId(assesManagement.getId());
        management.setStatus(assesManagement.getStatus());
        return assesManagementMapper.updateAssesManagement(assesManagement);
    }


    /**
     * 添加系统规则积分
     *
     * @param assesRuleSystems 系统规则
     * @return 结果
     */
    @Override
    public void insertAssesManagementSystem( List<AssesRuleSystem> assesRuleSystems,String startTime,String endTime,String deptTye){
        for(AssesRuleSystem rule : assesRuleSystems){
            String ruleType = rule.getRuleType();
            if("0".equals(ruleType)){
                insertAssesManagementByMeetingType(rule,startTime,endTime,deptTye);
            }else if("1".equals(ruleType)){
                //累计会议时长
                insertAssesManagementByMeetingTime(rule,startTime,endTime,deptTye);
            }else if("2".equals(ruleType)){
                //参加活动类型
                insertAssesManagementByActivityType(rule,startTime,endTime,deptTye);
            }else if("3".equals(ruleType)){
                //累计活动时长
                insertAssesManagementByActivityTime(rule,startTime,endTime,deptTye);
            }else if("4".equals(ruleType)){
                //提交总结类型
                insertPointsManagementByWorkSummaryType(rule,startTime,endTime,deptTye);
            }
        }
    }


    /**
     * 按照年度查询个人积分统计
     */
    @Override
    public TableDataInfo selectRank(AssesManagement assesManagement,String effectiveTerm){
        List<AssesRankVo> resultList = new ArrayList();
        Long pointsRuleId = assesManagement.getAssesRuleId();
        SysDept dept = new SysDept();
        List<SysDept> sysDepts = sysDeptService.selectDeptList(dept);
        //计算部门积分
        for(SysDept sysDept : sysDepts){
            String deptType = sysDept.getDeptType();
            //查询出部门对应的考核规则 (1个部门类型对应1个考核规则)
            AssesRule assesRule = new AssesRule();
            assesRule.setDeptType(deptType);
            assesRule.setEffectiveTerm(effectiveTerm);
            AssesRule assesRuleResult = assesRuleService.selectAssesRuleByAssesRule(assesRule);
            if(ObjectUtils.isEmpty(assesRuleResult)){
                continue;
            }
            //查询规则初始分
            String initialScore = assesRuleResult.getInitialScore();
            Float initial= Float.valueOf(initialScore);
            AssesRankVo assesRankVo = new AssesRankVo();
            assesRankVo.setDeptId(sysDept.getDeptId());
            assesRankVo.setDeptName(sysDept.getDeptName());
            assesRankVo.setAssesRuleId(assesRuleResult.getId());
            assesRankVo.setAssesRuleName(assesRuleResult.getAssesRuleName());
            //查询部门人工规则得分情况
            AssesManagement management = new AssesManagement();
            management.setAssesRuleId(assesRuleResult.getId());
            management.setStatus("1");
            management.setRuleCategory("0");
            management.setStartTime(assesManagement.getStartTime());
            management.setEndTime(assesManagement.getEndTime());
            management.setDeptId(sysDept.getDeptId());
            List<AssesManagement> assesManagementArtificial = assesManagementMapper.selectAssesManagementList(management);
            //系统规则
            management.setStatus("");
            management.setRuleCategory("1");
            management.setStartTime(assesManagement.getStartTime());
            management.setEndTime(assesManagement.getEndTime());
            management.setDeptId(sysDept.getDeptId());
            List<AssesManagement> assesManagementSystem = assesManagementMapper.selectAssesManagementList(management);
            assesManagementArtificial.addAll(assesManagementSystem);
            Float totalAddScore = 0f;
            Float totalSubtractScore = 0f;
            for(AssesManagement asses : assesManagementArtificial){
                String executeScore = asses.getExecuteScore();
                String modified = asses.getModified();
                if("0".equals(modified)){
                    //加分
                    totalAddScore = totalAddScore + Float.valueOf(executeScore);
                }else if("1".equals(modified)){
                    //扣分
                    totalSubtractScore = totalSubtractScore + Float.valueOf(executeScore);
                }
            }
            assesRankVo.setTotalAddScore(totalAddScore);
            assesRankVo.setTotalSubtractScore(totalSubtractScore);
            float total = initial + totalAddScore - totalSubtractScore;
            assesRankVo.setTotalScore(total);
            //查询部门对应人员人数
            SysUser user = new SysUser();
            user.setDeptId(sysDept.getDeptId());
            List<SysUser> sysUsers = sysUserMapper.selectUserList(user);
            assesRankVo.setUserCount(sysUsers.size());
            resultList.add(assesRankVo);
        }
        resultList = resultList.stream()
                .sorted(Comparator.comparing(AssesRankVo::getTotalScore).reversed())
                .collect(Collectors.toList());
        int index = 0;
        double lastAge = -1;
        // 并列排名后名次不间断
        for (AssesRankVo vo : resultList) {
            if (Double.compare(lastAge, vo.getTotalScore()) != 0) {
                lastAge = vo.getTotalScore();
                index++;
            }
            vo.setOrderNum(index);
        }
        if(!ObjectUtils.isEmpty(assesManagement.getDeptId())){
            resultList = resultList.stream().filter(o -> o.getDeptId().equals(assesManagement.getDeptId())).collect(Collectors.toList());
        }
        Integer num = resultList.size();
        Integer pageNum = assesManagement.getPageNum();
        Integer pageSize = assesManagement.getPageSize();
        List<AssesRankVo> list = resultList.stream().skip((pageNum - 1) * pageSize).limit(pageSize).collect(Collectors.toList());
        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setMsg("查询成功");
        rspData.setRows(list);
        rspData.setTotal(num);
        return rspData;
    }

    public void insertAssesManagementByMeetingType(AssesRuleSystem rule,String startTime,String endTime,String deptType){
        String firstCondition = rule.getFirstCondition();
        String conditionJudge = rule.getConditionJudge();
        String secondCondition = rule.getSecondCondition();
        String modified = rule.getModified();
        String pointsScore = rule.getAssesScore();
        //查询部门类型下所有部门
        SysDept sysDept = new SysDept();
        sysDept.setDeptType(deptType);
        List<SysDept> sysDepts = sysDeptService.selectDeptList(sysDept);
        for(SysDept dept : sysDepts){
            //查询部门召开会议次数
            MeetingManagement meetingManagement = new MeetingManagement();
            meetingManagement.setMeetingType(firstCondition);
            meetingManagement.setDeptId(dept.getDeptId());
            meetingManagement.setMeetingStartTime(startTime);
            meetingManagement.setMeetingEndTime(endTime);
            List<MeetingManagement> meetingManagements = meetingManagementService.selectMeetingManagementList(meetingManagement);
            int count = meetingManagements.size();
            AssesManagement management = new AssesManagement();
            management.setAssesRuleId(rule.getAssesRuleId());
            management.setAssesRuleSystemId(rule.getId());
            management.setAssesType(rule.getAssesType());
            management.setAssesProject(rule.getAssesProject());
            management.setAssesStandard(rule.getAssesStandard());
            management.setRuleCategory("1");
            management.setDeptId(dept.getDeptId());
            management.setDeptName(dept.getDeptName());
            management.setExecuteScore(pointsScore);
            if("0".equals(conditionJudge)){
                //大于
                if(count>Integer.valueOf(secondCondition)){
                    if("0".equals(modified)){
                        //加分
                        management.setModified("0");
                        insertAssesManagement(management);
                    }else{
                        //扣分
                        management.setModified("1");
                        insertAssesManagement(management);
                    }
                }
            }else if("1".equals(conditionJudge)){
                //小于
                if(count<Integer.valueOf(secondCondition)){
                    if("0".equals(modified)){
                        //加分
                        management.setModified("0");
                        insertAssesManagement(management);
                    }else{
                        //扣分
                        management.setModified("1");
                        insertAssesManagement(management);
                    }
                }
            }
        }
    }

    public void insertAssesManagementByMeetingTime(AssesRuleSystem rule,String startTime,String endTime,String deptType){
        String firstCondition = rule.getFirstCondition();
        String conditionJudge = rule.getConditionJudge();
        String secondCondition = rule.getSecondCondition();
        String modified = rule.getModified();
        String pointsScore = rule.getAssesScore();
        //查询部门类型下所有部门
        SysDept sysDept = new SysDept();
        sysDept.setDeptType(deptType);
        List<SysDept> sysDepts = sysDeptService.selectDeptList(sysDept);
        for(SysDept dept :sysDepts){
           //查询部门召开会议时间
            MeetingManagement meetingManagement = new MeetingManagement();
            meetingManagement.setMeetingType(firstCondition);
            meetingManagement.setDeptId(dept.getDeptId());
            meetingManagement.setMeetingStartTime(startTime);
            meetingManagement.setMeetingEndTime(endTime);
            List<MeetingManagement> meetingManagements = meetingManagementService.selectMeetingManagementList(meetingManagement);
            Long differenceTime = 0L;
            for(MeetingManagement meeting : meetingManagements){
                String meetingStartTime = meeting.getMeetingStartTime();
                String meetingEndTime = meeting.getMeetingEndTime();
                Date meetingStart = DateUtil.parse(meetingStartTime);
                Date meetingEnd = DateUtil.parse(meetingEndTime);
                long difference = meetingEnd.getTime() - meetingStart.getTime();
                differenceTime = differenceTime+difference;
            }
            //处理会议时长
            AssesManagement management = new AssesManagement();
            management.setAssesRuleId(rule.getAssesRuleId());
            management.setAssesRuleSystemId(rule.getId());
            management.setAssesType(rule.getAssesType());
            management.setAssesProject(rule.getAssesProject());
            management.setAssesStandard(rule.getAssesStandard());
            management.setRuleCategory("1");
            management.setDeptId(dept.getDeptId());
            management.setDeptName(dept.getDeptName());
            management.setExecuteScore(pointsScore);
            long hour = differenceTime / (60 * 60 * 1000);
            if("0".equals(conditionJudge)){
                //大于
                if(hour>Integer.valueOf(secondCondition)){
                    if("0".equals(modified)){
                        //加分
                        management.setModified("0");
                        insertAssesManagement(management);
                    }else{
                        //扣分
                        management.setModified("1");
                        insertAssesManagement(management);
                    }
                }
            }else if("1".equals(conditionJudge)){
                //小于
                if(hour<Integer.valueOf(secondCondition)){
                    if("0".equals(modified)){
                        //加分
                        management.setModified("0");
                        insertAssesManagement(management);
                    }else{
                        //扣分
                        management.setModified("1");
                        insertAssesManagement(management);
                    }
                }
            }
        }
    }

    public void insertAssesManagementByActivityType(AssesRuleSystem rule,String startTime,String endTime,String deptType){
        String firstCondition = rule.getFirstCondition();
        String conditionJudge = rule.getConditionJudge();
        String secondCondition = rule.getSecondCondition();
        String modified = rule.getModified();
        String pointsScore = rule.getAssesScore();
        //查询部门类型下所有部门
        SysDept sysDept = new SysDept();
        sysDept.setDeptType(deptType);
        List<SysDept> sysDepts = sysDeptService.selectDeptList(sysDept);
        for(SysDept dept : sysDepts){
            //查询部门召开活动次数
            ActivityManagement activityManagement = new ActivityManagement();
            activityManagement.setActivityType(firstCondition);
            activityManagement.setDeptId(dept.getDeptId());
            activityManagement.setActivityStartTime(startTime);
            activityManagement.setActivityEndTime(endTime);
            List<ActivityManagement> activityManagements = activityManagementService.selectActivityManagementList(activityManagement);
            int count = activityManagements.size();
            AssesManagement management = new AssesManagement();
            management.setAssesRuleId(rule.getAssesRuleId());
            management.setAssesRuleSystemId(rule.getId());
            management.setAssesType(rule.getAssesType());
            management.setAssesProject(rule.getAssesProject());
            management.setAssesStandard(rule.getAssesStandard());
            management.setRuleCategory("1");
            management.setDeptId(dept.getDeptId());
            management.setDeptName(dept.getDeptName());
            management.setExecuteScore(pointsScore);
            if("0".equals(conditionJudge)){
                //大于
                if(count>Integer.valueOf(secondCondition)){
                    if("0".equals(modified)){
                        //加分
                        management.setModified("0");
                        insertAssesManagement(management);
                    }else{
                        //扣分
                        management.setModified("1");
                        insertAssesManagement(management);
                    }
                }
            }else if("1".equals(conditionJudge)){
                //小于
                if(count<Integer.valueOf(secondCondition)){
                    if("0".equals(modified)){
                        //加分
                        management.setModified("0");
                        insertAssesManagement(management);
                    }else{
                        //扣分
                        management.setModified("1");
                        insertAssesManagement(management);
                    }
                }
            }
        }
    }

    public void insertAssesManagementByActivityTime(AssesRuleSystem rule,String startTime,String endTime,String deptType) {
        String firstCondition = rule.getFirstCondition();
        String conditionJudge = rule.getConditionJudge();
        String secondCondition = rule.getSecondCondition();
        String modified = rule.getModified();
        String pointsScore = rule.getAssesScore();
        //查询部门类型下所有部门
        SysDept sysDept = new SysDept();
        sysDept.setDeptType(deptType);
        List<SysDept> sysDepts = sysDeptService.selectDeptList(sysDept);
        for (SysDept dept : sysDepts) {
            //查询部门召开活动时间
            ActivityManagement activityManagement = new ActivityManagement();
            activityManagement.setActivityType(firstCondition);
            activityManagement.setDeptId(dept.getDeptId());
            activityManagement.setActivityStartTime(startTime);
            activityManagement.setActivityEndTime(endTime);
            List<ActivityManagement> activityManagements = activityManagementService.selectActivityManagementList(activityManagement);
            Long differenceTime = 0L;
            for (ActivityManagement activity : activityManagements) {
                String activityStartTime = activity.getActivityStartTime();
                String activityEndTime = activity.getActivityEndTime();
                Date activityStart = DateUtil.parse(activityStartTime);
                Date activityEnd = DateUtil.parse(activityEndTime);
                long difference = activityEnd.getTime() - activityStart.getTime();
                differenceTime = differenceTime + difference;
            }
            //处理会议时长
            AssesManagement management = new AssesManagement();
            management.setAssesRuleId(rule.getAssesRuleId());
            management.setAssesRuleSystemId(rule.getId());
            management.setAssesType(rule.getAssesType());
            management.setAssesProject(rule.getAssesProject());
            management.setAssesStandard(rule.getAssesStandard());
            management.setRuleCategory("1");
            management.setDeptId(dept.getDeptId());
            management.setDeptName(dept.getDeptName());
            management.setExecuteScore(pointsScore);
            long hour = differenceTime / (60 * 60 * 1000);
            if("0".equals(conditionJudge)){
                //大于
                if(hour>Integer.valueOf(secondCondition)){
                    if("0".equals(modified)){
                        //加分
                        management.setModified("0");
                        insertAssesManagement(management);
                    }else{
                        //扣分
                        management.setModified("1");
                        insertAssesManagement(management);
                    }
                }
            }else if("1".equals(conditionJudge)){
                //小于
                if(hour<Integer.valueOf(secondCondition)){
                    if("0".equals(modified)){
                        //加分
                        management.setModified("0");
                        insertAssesManagement(management);
                    }else{
                        //扣分
                        management.setModified("1");
                        insertAssesManagement(management);
                    }
                }
            }
        }
    }

    public void insertPointsManagementByWorkSummaryType(AssesRuleSystem rule,String startTime,String endTime,String deptType){
        String firstCondition = rule.getFirstCondition();
        String conditionJudge = rule.getConditionJudge();
        String secondCondition = rule.getSecondCondition();
        String modified = rule.getModified();
        String pointsScore = rule.getAssesScore();
        //查询部门类型下所有部门
        SysDept sysDept = new SysDept();
        sysDept.setDeptType(deptType);
        List<SysDept> sysDepts = sysDeptService.selectDeptList(sysDept);
        for(SysDept dept : sysDepts){
            //查询人员时间范围内工作总结次数
            WorkSummary workSummary = new WorkSummary();
            workSummary.setDeptId(dept.getDeptId());
            workSummary.setSummaryType(firstCondition);
            workSummary.setStartTime(startTime);
            workSummary.setEndTime(endTime);
            //根据工作总结类型查询
            List<WorkSummary> workSummaries = workSummaryService.selectWorkSummaryList(workSummary);
            int count = workSummaries.size();
            AssesManagement management = new AssesManagement();
            management.setAssesRuleId(rule.getAssesRuleId());
            management.setAssesRuleSystemId(rule.getId());
            management.setAssesType(rule.getAssesType());
            management.setAssesProject(rule.getAssesProject());
            management.setAssesStandard(rule.getAssesStandard());
            management.setRuleCategory("1");
            management.setDeptId(dept.getDeptId());
            management.setDeptName(dept.getDeptName());
            management.setExecuteScore(pointsScore);
            if("0".equals(conditionJudge)){
                //大于
                if(count>Integer.valueOf(secondCondition)){
                    if("0".equals(modified)){
                        //加分
                        management.setModified("0");
                        insertAssesManagement(management);
                    }else{
                        //扣分
                        management.setModified("1");
                        insertAssesManagement(management);
                    }
                }
            }else if("1".equals(conditionJudge)){
                //小于
                if(count<Integer.valueOf(secondCondition)){
                    if("0".equals(modified)){
                        //加分
                        management.setModified("0");
                        insertAssesManagement(management);
                    }else{
                        //扣分
                        management.setModified("1");
                        insertAssesManagement(management);
                    }
                }
            }
        }
    }
}
